#include "svgnodegroup.h"

#include <QStyleOptionGraphicsItem>
#include "svgnodeelementfactory.h"
#include "util.h"

SvgNodeGroup::SvgNodeGroup(SvgNode *parent)
	:SvgNodeContainer(parent),
	m_framePad(10)
{

}

void SvgNodeGroup::paint(QPainter *painter,
	const QStyleOptionGraphicsItem *option,
	QWidget *widget){

	KUnitItem::paint(painter, option, widget);
	if (option->state & QStyle::State_Selected){
		QPen pen = painter->pen();
		pen.setStyle(Qt::DashLine);
		painter->setPen(pen);
		painter->drawRect(m_frame);
	}
	

}
void SvgNodeGroup::fromXmlImpl(const QDomElement &xml) {
	QDomNodeList subs = xml.childNodes();

	for (int i = 0; i < subs.count(); i++){

		QDomNode xmlNode = subs.item(i);

		
		SvgNode *node = SvgNodeElementFactory::createNode(xmlNode.toElement());
		if (!node)
			continue;

		node->fromXml(xmlNode.toElement());
		this->add(node);
		node->setFlag(QGraphicsItem::ItemIsSelectable, false);
		node->setFlag(QGraphicsItem::ItemIsFocusable, false);
		node->setFlag(QGraphicsItem::ItemIsMovable, false);

	}

	updateFrame();
	updateShape();
}

QDomElement SvgNodeGroup::toXmlImpl(QDomElement &parent) const{
	QDomElement curr = SvgNodeContainer::toXmlImpl(parent);
	curr.setAttribute("group", "1");
	return curr;
}

void SvgNodeGroup::updateFrame(){
	SvgNodeContainer::updateFrame();

	//pad frame
	m_frame = QRectF(m_frame.x() - m_framePad, m_frame.y() - m_framePad, m_frame.width() + 2 * m_framePad, m_frame.height() + 2 * m_framePad);
}
void SvgNodeGroup::updateShape(){
	m_shape = QPainterPath();
	/*m_shape.addRect(m_frame);
	return;*/
	foreach(SvgNode *node, m_childern)
		m_shape.addPath(node->mapToParent(node->shape()));
}



void SvgNodeGroup::onResize(QRectF rect){
	QRectF rectNew = rect;
	//fix
	rectNew = QRectF(rectNew.x() + m_strokeWidth / 2.f + m_framePad, rectNew.y() + m_strokeWidth / 2.f + m_framePad, rectNew.width() - m_strokeWidth - 2 * m_framePad, rectNew.height() - m_strokeWidth - 2 * m_framePad);
	QRectF rectOld = QRectF(m_frame.x() + m_strokeWidth / 2.f + m_framePad, m_frame.y() + m_strokeWidth / 2.f + m_framePad, m_frame.width() - m_strokeWidth - 2 * m_framePad, m_frame.height() - m_strokeWidth - 2 * m_framePad);

	QPointF pTopLeft = m_frame.topLeft() + QPointF(m_strokeWidth / 2.f, m_strokeWidth / 2.f);
	QPointF originOffset = fixedOriginPoint() - pTopLeft;

	QPointF fixedPoint;
	if (this->resizeFixedPoint(rectNew, rectOld, fixedPoint))
	{
		qreal xScale = rectNew.width() / rectOld.width();
		qreal yScale = rectNew.height() / rectOld.height();


		if (fixedPoint == QPointF(rectOld.x(), rectOld.y()))
		{
			foreach(SvgNode *node, m_childern){
				
				QRectF frame = node->m_frame;
				frame.setWidth(frame.width()*xScale);
				frame.setHeight(frame.height()*yScale);
				node->onResize(frame);
				
				frame = this->mapRectWithNoTransform(node);
				

				//fix
				frame = QRectF(frame.x() + node->strokeWidth() / 2.f, frame.y() + node->strokeWidth() / 2.f, frame.width() - node->strokeWidth(), frame.height() - node->strokeWidth());
				QPointF thisFixedPoint = frame.topLeft();
				QPointF offset = (thisFixedPoint - fixedPoint);
				offset.setX(offset.x()*xScale);
				offset.setY(offset.y()*yScale);
				
				node->setPos(node->pos() + fixedPoint + offset - thisFixedPoint);
			}
		}
		else if (fixedPoint == QPointF(rectOld.x() + rectOld.width(), rectOld.y())){
			foreach(SvgNode *node, m_childern){
				QRectF frame = node->m_frame;
				QPointF thisFixedPoint = frame.topRight();
				frame = QRectF(thisFixedPoint.x() - frame.width()*xScale, thisFixedPoint.y() , frame.width()*xScale, frame.height()*yScale);

				node->onResize(frame);

				frame = this->mapRectWithNoTransform(node);
				//fix
				frame = QRectF(frame.x() + node->strokeWidth() / 2.f, frame.y() + node->strokeWidth() / 2.f, frame.width() - node->strokeWidth(), frame.height() - node->strokeWidth());
				thisFixedPoint = frame.topRight();
				QPointF offset = (thisFixedPoint - fixedPoint);
				offset.setX(offset.x()*xScale);
				offset.setY(offset.y()*yScale);
				offset = fixedPoint + offset - thisFixedPoint;
				node->setPos(node->pos() + offset);
			}
		}
		else if (fixedPoint == QPointF(rectOld.x() + rectOld.width(), rectOld.y() + rectOld.height())){
			foreach(SvgNode *node, m_childern){
				QRectF frame = node->m_frame;
				QPointF thisFixedPoint = frame.bottomRight();
				frame = QRectF(thisFixedPoint.x() - frame.width()*xScale, thisFixedPoint.y() - frame.height()*yScale, frame.width()*xScale, frame.height()*yScale);

				node->onResize(frame);

				frame = this->mapRectWithNoTransform(node);
				//fix
				frame = QRectF(frame.x() + node->strokeWidth() / 2.f, frame.y() + node->strokeWidth() / 2.f, frame.width() - node->strokeWidth(), frame.height() - node->strokeWidth());
				thisFixedPoint = frame.bottomRight();
				QPointF offset = (thisFixedPoint - fixedPoint);
				offset.setX(offset.x()*xScale);
				offset.setY(offset.y()*yScale);
				offset = fixedPoint + offset - thisFixedPoint;
				node->setPos(node->pos() + offset);
			}
		}
		else if (fixedPoint == QPointF(rectOld.x(), rectOld.y() + rectOld.height())){
			foreach(SvgNode *node, m_childern){
				QRectF frame = node->m_frame;
				QPointF thisFixedPoint = frame.bottomLeft();
				frame = QRectF(thisFixedPoint.x(), thisFixedPoint.y() - frame.height()*yScale, frame.width()*xScale, frame.height()*yScale);

				node->onResize(frame);

				frame = this->mapRectWithNoTransform(node);
				//fix
				frame = QRectF(frame.x() + node->strokeWidth() / 2.f, frame.y() + node->strokeWidth() / 2.f, frame.width() - node->strokeWidth(), frame.height() - node->strokeWidth());
				thisFixedPoint = frame.bottomLeft();
				QPointF offset = (thisFixedPoint - fixedPoint);
				offset.setX(offset.x()*xScale);
				offset.setY(offset.y()*yScale);
				offset = fixedPoint + offset - thisFixedPoint;
				node->setPos(node->pos() + offset);
			}
		}
		else{
			//error
			//throw
			return;
		}

		
	}

	
	updateFrame();
	updateShape();
	SvgNode::onResize(rect);
}


void SvgNodeGroup::initGroup(QList<SvgNode*> list){
	foreach(SvgNode *node, list){
		if (node->parentNode())
			node->parentNode()->remove(node);
		this->add(node);

		node->setSelected(false);
		node->setFlag(QGraphicsItem::ItemIsSelectable, false);
		node->setFlag(QGraphicsItem::ItemIsFocusable, false);
		node->setFlag(QGraphicsItem::ItemIsMovable, false);
	}
	this->setSelected(true);
}
void SvgNodeGroup::destroyGroup(){
	//transform
	this->setSelected(false);
	QPointF thisOffset = fixedOriginPoint() - (this->frame().topLeft() + QPointF(this->strokeWidth() / 2.f, this->strokeWidth() / 2.f));
	QPointF thisCenter = this->m_frame.center();
	SvgNode *parent = this->parentNode();
	foreach(SvgNode *obj, m_childern){
		QPointF pTopLeft = obj->frame().topLeft() + QPointF(obj->strokeWidth() / 2.f, obj->strokeWidth() / 2.f);
		QPointF pCenter = obj->mapFromParent(thisCenter);
		pTopLeft = Util::rotateWithCenter(pTopLeft, obj->m_frame.center(), -obj->m_rotationAngle);
		pCenter = Util::rotateWithCenter(pCenter, obj->m_frame.center(), -obj->m_rotationAngle);

		QPointF origin = Util::rotateWithCenter(pTopLeft, pCenter, -this->m_rotationAngle);
		pCenter = Util::rotateWithCenter(obj->m_frame.center(), pCenter, -this->m_rotationAngle);
		origin = Util::rotateWithCenter(origin, pCenter, this->m_rotationAngle);
		QPointF offset = origin - pTopLeft;

		QPointF pos = this->pos() + obj->pos() + thisOffset;
		obj->setPos(pos.x() + offset.x(), pos.y() + offset.y());
		obj->setAngle(this->m_rotationAngle);
	}
	//remove

	foreach(SvgNode *obj, m_childern){
		this->remove(obj);
		parent->add(obj);
		obj->setFlag(QGraphicsItem::ItemIsSelectable, true);
		obj->setFlag(QGraphicsItem::ItemIsFocusable, true);
		obj->setFlag(QGraphicsItem::ItemIsMovable, true);
		obj->setSelected(true);
	}
	parent->remove(this);
	this->deleteLater();
	
}





QList<QPointF> SvgNodeGroup::alignPoints(QPointF &center){
	QList<QPointF> list;
	QPointF fixLeftTop = fixedOriginPoint();

	list.append(QPointF(0, 0) + fixLeftTop);
	list.append(QPointF(0, m_frame.height() - m_strokeWidth) + fixLeftTop);
	list.append(QPointF(m_frame.width() - m_strokeWidth, 0) + fixLeftTop);
	list.append(QPointF(m_frame.width() - m_strokeWidth, m_frame.height() - m_strokeWidth) + fixLeftTop);

	center = (QPointF(m_frame.width() - m_strokeWidth, m_frame.height() - m_strokeWidth)) / 2. + fixLeftTop;;

	return list;
}